/* eslint-disable react-hooks/exhaustive-deps */
import React, { useCallback, useEffect, useState, useRef } from 'react';
import { createPortal } from 'react-dom';
import Dialog from './Dialog';
import './Modal.css';

let instance = null;
export default function Modal(props) {
  const { children, onOk, onCancel, footer, title } = props;
  const overlayRef = useRef(null);
  const contentRef = useRef(null);
  const [visible, setVisible] = useState(props.visible || false);

  useEffect(() => {
    if (!instance) {
      instance = document.createElement('div');
      instance.className = 'modal_box';
      document.body.appendChild(instance);
    }
  }, []);

  const contentAnimation = [
    { opacity: 0, transform: 'translateY(-30%)' },
    { opacity: 1, transform: 'translateY(-50%)' },
  ];
  const overlayAnimation = [{ opacity: 0 }, { opacity: 1 }];
  // 时间函数列表
  const animationSettings = { duration: 150, fill: 'both' };
  const reverseAnimationSettings = {
    ...animationSettings,
    direction: 'reverse',
  };

  // 动画开始
  const animateIn = useCallback(async () => {
   await Promise.all([
    contentRef.current?.animate(contentAnimation, animationSettings),
    overlayRef.current?.animate(overlayAnimation, animationSettings)
   ])
    setVisible(true);
  }, [animationSettings, overlayAnimation, contentAnimation]);

  // 动画结束
  const animateOut = useCallback(async () => {
    await Promise.all([
      contentRef.current?.animate(contentAnimation, reverseAnimationSettings).finished,
      overlayRef.current?.animate(overlayAnimation, reverseAnimationSettings).finished,
    ]);
    setVisible(false);
  }, [contentAnimation, overlayAnimation, reverseAnimationSettings]);

  useEffect(() => {
    if (props.visible) {
      animateIn();
    } else {
      animateOut();
    }
  }, [props.visible, animateIn, animateOut]);

  return (
    visible &&
    createPortal(
      <div className="Modal_mask" ref={overlayRef}>
        <Dialog
          ref={contentRef}
          visible={visible}
          title={title}
          onOk={onOk}
          onCancel={onCancel}
          footer={footer}
        >
          {children}
        </Dialog>
      </div>,
      instance
    )
  );
}
